﻿#define Test
using HalconDotNet;
using KSJCamera;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CameraModule
{
    public class KSJCarmera : ICam
    {
        private int cameraNum;

        public int CameraNum { get => cameraNum; set => cameraNum = value; }

        public void CloseCamera()
        {
            for (int i = 0; i < CameraNum; i++)
            {
                //关闭相机视频流
                KSJApiBase.KSJ_PreviewStart(i, false);
            }
            //反初始化
            KSJApiBase.KSJ_UnInit();
           
        }
        public HObject GrabImage(int index)
        {
            HObject image = null;
            if (index>=cameraNum) return image;//判断编号是否超过相机数
            int Width=0, Height=0, BitCount=0;
            KSJApiBase.KSJ_CaptureGetSizeEx(index, ref Width, ref Height, ref BitCount);//获取相机宽高
            if (BitCount==24)
            {
                image= ConvertToHObject(Width, Height);
            }
            return image;
        }
#if Test
        public HObject GrabImage(string path)
        {
            HOperatorSet.ReadImage(out HObject image, new HTuple(path));
            return image;
        }
#endif


        public void IniCamera()
        {
            //枚举相机
            CameraNum= KSJApiBase.KSJ_DeviceGetCount();
            for (int i = 0; i < CameraNum; i++)
            {
                //启动视频流，用户必须先通过KSJ_PreviewSetPos来设置视频显示的窗口及位置创建一个预览窗口，否则将看不到预览视频流。
                //开始采集
                KSJApiBase.KSJ_PreviewStart(i, true);
            }
        }

        public void OpenCamera()
        {
            //初始化相机
            KSJApiBase.KSJ_Init();
        }
        /// <summary>
        /// 24位彩色图像转HObject
        /// </summary>
        /// <param name="nCaptureWidth"></param>
        /// <param name="nCaptureHeight"></param>
        /// <returns></returns>
        private HObject ConvertToHObject(int nCaptureWidth,int nCaptureHeight)
        {
            HObject image = new HObject();
            //申请图像数据内存(变量的作用域  值类型  引用类型）
            byte[] buffer = new byte[nCaptureWidth * nCaptureHeight * 3];
            int bytesPerLineRGB = (nCaptureWidth * 3 + 3) / 4 * 4;//彩色图像每行所占字节数
            int bytesPerLineGray = (nCaptureWidth + 3) / 4 * 4;//灰度图像每行所占字节数
            byte[] bufferB = new byte[bytesPerLineGray * nCaptureHeight];//蓝色图像的数据数组
            byte[] bufferG = new byte[bytesPerLineGray * nCaptureHeight];//绿色图像的数据数组
            byte[] bufferR = new byte[bytesPerLineGray * nCaptureHeight];//红色图像的数据数组
            for (int i = 0; i < nCaptureHeight; i++)
            {
                for (int j = 0; j < nCaptureWidth; j++)
                {
                    bufferB[i * bytesPerLineGray + j] = buffer[i * bytesPerLineRGB + j * 3 + 0];//蓝色分量
                    bufferG[i * bytesPerLineGray + j] = buffer[i * bytesPerLineRGB + j * 3 + 1];//绿色分量
                    bufferR[i * bytesPerLineGray + j] = buffer[i * bytesPerLineRGB + j * 3 + 2];//红色分量
                }
            }
            unsafe
            {
                fixed (byte* pr = bufferR, pg = bufferG, pb = bufferB)
                {
                    HOperatorSet.GenImage3Extern(out image, "byte", nCaptureWidth, nCaptureHeight, new IntPtr(pr), new IntPtr(pg), new IntPtr(pb), 0);
                }
            }
            return image;
        }
    }
}
